package cn.iocoder.yudao.module.shop.controller.admin.member;

import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.recharge.PayWalletRechargeCreateReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.recharge.PayWalletRechargePageReqVO;
import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.recharge.PayWalletRechargeRespVO;
import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO;
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient;
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletRechargeService;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
import cn.iocoder.yudao.module.shop.controller.admin.member.vo.*;
import cn.iocoder.yudao.module.shop.convert.statistics.ShopStatisticsConvert;
import cn.iocoder.yudao.module.shop.dal.dataobject.price.ShopPriceDO;
import cn.iocoder.yudao.module.shop.dal.dataobject.statistics.ShopMemberStatisticsDO;
import cn.iocoder.yudao.module.shop.dal.dataobject.statistics.ShopWalletStatisticsDO;
import cn.iocoder.yudao.module.shop.service.itemtimesrecharge.ShopItemTimesRechargeService;
import cn.iocoder.yudao.module.shop.service.member.ShopMemberService;
import cn.iocoder.yudao.module.shop.service.memberpay.ShopMemberPayItemService;
import cn.iocoder.yudao.module.shop.service.price.ShopPriceService;
import cn.iocoder.yudao.module.shop.service.refundcardrecord.ShopRefundCardRecordService;
import cn.iocoder.yudao.module.shop.service.statistics.ShopStatisticsService;
import com.alipay.api.domain.ResourceDataVO;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;


@Tag(name = "管理后台 - 会员详细接口")
@RestController
@RequestMapping("/shop/member")
@Validated
public class ShopMemberController {

    @Resource
    private PayWalletRechargeService payWalletRechargeService;

    @Resource
    private PayOrderService payOrderService;

    @Resource
    private ShopMemberService shopMemberService;

    @Resource
    private ShopStatisticsService shopStatisticsService;

    @Resource
    private PayWalletService payWalletService;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private ShopRefundCardRecordService refundCardRecordService;

    @Resource
    private ShopMemberPayItemService shopMemberPayItemService;

    @Resource
    private ShopPriceService shopPriceService;





    @GetMapping("/page")
    @Operation(summary = "获得会员用户分页")
    @PreAuthorize("@ss.hasPermission('member:user:query')")
    public CommonResult<PageResult<MemberUserDetailRespVO>> getUserPage(@Valid MemberUserPageReqVO pageVO) {
        return success(shopMemberService.getUserPage(pageVO));
    }

    @PostMapping("/search")
    @Operation(summary = "搜索用户")
    @PreAuthorize("@ss.hasPermission('member:user:query')")
    public CommonResult<List<ShopMemberSearchRespVO>> searchMembers(@Valid @RequestBody MemberUserSearchReqVO reqVO){
        return success(shopMemberService.searchMember(reqVO));
    }

    @PostMapping("/create")
    @Operation(summary = "店铺创建会员")
    public CommonResult<Boolean> createMember(@Valid @RequestBody MemberUserCreateReqVO createReqVO){
        return success(shopMemberService.createMember(createReqVO));
    }

    @PostMapping("/quickcreate")
    @Operation(summary = "店铺快速创建临时会员,没有手机号的")
    public CommonResult<Boolean> quickCreateMember(@Valid @RequestBody MemberUserCreateReqVO createReqVO){
        return success(shopMemberService.quickCreateMember(createReqVO));
    }

    @PostMapping("/update")
    @Operation(summary = "更新会员数据")
    public CommonResult<Boolean> updateMember(@Valid @RequestBody MemberUserUpdateReqVO updateReqVO){
        return success(shopMemberService.updateMember(updateReqVO));
    }

    @PostMapping("/timesrecharge")
    @Operation(summary = "店铺会员项目次数充值")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> timesRecharge(@Valid @RequestBody TimesRechargeCreateReqVO reqVO){
        reqVO.setPayPrice(reqVO.getPayPrice() * 100);

        shopMemberService.timesRecharge(reqVO);
        payWalletService.addTotalRecharge(reqVO.getMemberId(), UserTypeEnum.MEMBER.getValue(), reqVO.getPayPrice());
        shopStatisticsService.recordTimesChargePay(reqVO.getPayPrice(), reqVO.getMemberId(), reqVO.getUserId(), reqVO.getIsFirst(), reqVO.getTenantId());

        return success(true);
    }

    @PostMapping("/recharge")
    @Operation(summary = "店铺会员充值")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> walletRecharge(@Valid  @RequestBody PayWalletRechargeCreateReqVO reqVO) {

        Integer payPrice = reqVO.getPayPrice() * 100;
        Integer bonusPrice = reqVO.getBonusPrice();
        if(bonusPrice == null){
            bonusPrice = 0;
        }

        bonusPrice *= 100;

        // 创建订单 客户端发来单位是元
        PayWalletRechargeDO walletRecharge = payWalletRechargeService.createWalletRecharge(
                reqVO.getUserId(), UserTypeEnum.MEMBER.getValue(), "http://127.0.0.1", payPrice, bonusPrice, reqVO.getPackageId(), "店内会员充值");

        // 提交订单
        PayOrderSubmitReqVO submitReqVO = new PayOrderSubmitReqVO();
        submitReqVO.setChannelCode(PayChannelEnum.MOCK.getCode());
        submitReqVO.setDisplayMode(PayOrderDisplayModeEnum.NONE.getMode());
        submitReqVO.setReturnUrl("http://127.0.0.1");
        submitReqVO.setId(walletRecharge.getPayOrderId());
        Map<String, String> channelExtras = Maps.newHashMapWithExpectedSize(2);
        channelExtras.put(WalletPayClient.USER_ID_KEY, String.valueOf(reqVO.getUserId()));
        channelExtras.put(WalletPayClient.USER_TYPE_KEY, String.valueOf(UserTypeEnum.MEMBER.getValue()));
        submitReqVO.setChannelExtras(channelExtras);
        payOrderService.submitOrder(submitReqVO, "http://127.0.0.1");

        shopStatisticsService.recordPayOrder(walletRecharge, reqVO.getUserId(), reqVO.getMasterId(), reqVO.getIsFirst());

        return success(true);
    }

    @PostMapping("/refundcard")
    @Operation(summary = "店铺会员退卡")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> cancelCard(@Valid @RequestBody MemberCancelcardReqVO reqVO){
        MemberUserRespDTO member= memberUserApi.getUser(reqVO.getMemberId());
        if(member == null){
            return success(false);
        }

        PayWalletDO wallet = payWalletService.getWallet(member.getId(), UserTypeEnum.MEMBER.getValue());
        if(wallet == null)
        {
            return success(false);
        }

        if(wallet.getBalance() <= 0){
            return success(false);
        }

        refundCardRecordService.createRefundCardRecord(member, wallet, reqVO.getComment(), reqVO.getRefundBalance());

        payWalletService.reduceWalletBalance(wallet.getId(), member.getId(), PayWalletBizTypeEnum.SHOP_REFUND, wallet.getBalance());

        ShopPriceDO defaultPriceDo = shopPriceService.getDefaultPrice();
        if(defaultPriceDo != null) {
            shopMemberPayItemService.updateMemberPayItem(defaultPriceDo.getId(), member.getId());
        }

        return success(true);
    }

    @PostMapping("/statistics")
    @Operation(summary = "店铺会员充值")
    public CommonResult<MemberUserStatisticsRespVO> getStatisticsInfo(@RequestBody MemberUserStatisticsReqVO reqVO){
        ShopMemberStatisticsDO memberStatisticsDO = shopStatisticsService.getMemberStatistics(reqVO);
        ShopWalletStatisticsDO walletStatisticsDO = shopStatisticsService.getWalletStatistics(reqVO);

        return success(ShopStatisticsConvert.INSTANCE.convert(memberStatisticsDO, walletStatisticsDO));
    }

    @PostMapping("/detail")
    @Operation(summary = "店铺会员充值")
    public CommonResult<ShopMemberDetailRespVO> getMemberDetail(@Valid  @RequestBody ShopMemberDetailReqVO reqVO){
        return success(shopMemberService.getMemberDetail(reqVO.getMemberId(), reqVO.getOrderCount()));
    }

    @GetMapping("/recharge-page")
    @Operation(summary = "充值记录页")
    public CommonResult<PageResult<MemberRechargeRespVO>> page(@Valid PayWalletRechargePageReqVO pageReqVO){
        PageResult<PayWalletRechargeDO> pageResult = payWalletRechargeService.getOrderPage(pageReqVO);

        List<Long> walletIds = CollectionUtils.convertList(pageResult.getList(), PayWalletRechargeDO::getWalletId);
        List<PayWalletDO> walltList = payWalletService.getWallets(walletIds);

        List<Long> userIds = CollectionUtils.convertList(walltList, PayWalletDO::getUserId);
        List<MemberUserRespDTO> memberList = memberUserApi.getUserList(userIds);

        Map<Long, MemberUserRespDTO> memberMap =  CollectionUtils.convertMap(memberList, MemberUserRespDTO::getId);


        Map<Long, MemberUserRespDTO> walletMemberMap = new HashMap<>();
        for(int i = 0; i<walltList.size(); i++){
            PayWalletDO walletDO = walltList.get(i);
            if(!walletMemberMap.containsKey(walletDO.getId())){
                walletMemberMap.put(walletDO.getId(), memberMap.get(walletDO.getUserId()));
            }
        }

        List<MemberRechargeRespVO> list = new ArrayList<>();

        for(int i = 0; i<pageResult.getList().size(); i++){
            PayWalletRechargeDO recharge = pageResult.getList().get(i);
            MemberRechargeRespVO respVO = new MemberRechargeRespVO();
            respVO.setRecharge(recharge);
            respVO.setMember(walletMemberMap.get(recharge.getWalletId()));

            list.add(respVO);
        }

        return success(new PageResult<>(list, pageResult.getTotal()));
    }
}
